react antd table 拖拽表格
需要安装插件
npm install react-dnd react-dnd-html5-backend
封装拖拽表格
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { Table } from 'antd';
import update from 'immutability-helper';
const ItemTypes = {
ROW: 'row',
};
function DragTable(props) {
const {
dataSource,
columns,
onChange,
rowSelection,
pagination,
...tableProps
} = props;
const [list, setList] = useState([]);
useEffect(() => {
setList(dataSource);
}, [dataSource]);
const handleDrag = useCallback(
(col, hoverIndex) => {
if (!col.record) return;
let dragItem = col.record;
let newList = [];
//组内交换顺序
newList = update(list, {
$splice: [
[col.index, 1],
[hoverIndex, 0, dragItem],
],
});
setList(newList);
onChange(newList)
},
[list]
);
const DraggableRow = (props) => {
const {
index,
record,
handleDrag,
rowSelection,
pagination,
...restProps
} = props;
const ref = useRef(null);
// 接收
const [{ isOver, canDrop }, drop] = useDrop({
accept: ItemTypes.ROW,
drop: (col) => handleDrag(col, index),
canDrop: (item:any) => {
// setError(undefined);
const filter = list.filter((it) => it.id === item.id);
if (!!filter.length) {
// setError('数据已经被放置');
return false;
}
return true;
},
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
});
const rowStyle = { ...restProps.style };
if (isOver && canDrop) {
rowStyle.background = '#f0f4f8';
}
// 拖拽
const [{ isDragging }, drag] = useDrag({
// item: { type: ItemTypes.ROW, record, index },
type: ItemTypes.ROW,
item: () => {
return { record, index };
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const opacity = isDragging ? 0 : 1;
drag(drop(ref));
return <tr ref={ref} {...restProps} style={{ ...rowStyle, opacity }}></tr>;
};
const components = {
body: {
row: DraggableRow,
},
};
return (
<DndProvider backend={HTML5Backend}>
<Table
className="single-table"
{...tableProps}
components={components}
dataSource={list}
columns={columns}
onRow={(record, index) => ({
record,
index,
handleDrag,
})}
/>
</DndProvider>
);
}
export default DragTable;
使用, 需要有id
<DragTable
dataSource={dataSource.map((it,index)=> ({ ...it, id: index + 1 }))}
columns={columns}
rowKey={(record, index): string => `${record.key}-${index.toString()}`}
style={{ width: '100%' }}
onChange={value=> setDataSource(value)}
/>